﻿using BCore.Identity.Users.Caching;
using Core.Caching;
using Core.Helpers;
using Core.Identity.Common.Interfaces.Common.Interfaces;
using Core.Interfaces.Users;
using Core.Models;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;

namespace Core.Identity.Users.Features.Commands.UpdateMine;

#nullable disable

/// <summary>
/// 修改我的信息
/// </summary>
public class UpdateMineCommand : ICacheInvalidatorRequest<Result<bool>>
{
    /// <summary>
    /// 电子邮箱
    /// </summary>
    public string Email { get; set; }
    /// <summary>
    /// 昵称
    /// </summary>
    public required string Nickname { get; set; }
    /// <summary>
    /// 手机号码
    /// </summary>
    public required string PhoneNumber { get; set; }
    /// <summary>
    /// 设置签名
    /// </summary>
    public string Signature { get; set; }

    [JsonIgnore]
    public IEnumerable<string> Tags => UsersCacheKey.Tags;
}
public class UpdateMineCommandHandler(IIdentityDbContext dbContext,
    ICurrentUserService currentUserService) : IRequestHandler<UpdateMineCommand, Result<bool>>
{

    public async Task<Result<bool>> Handle(UpdateMineCommand request, CancellationToken cancellationToken)
    {
        var userId = currentUserService.GetUserId();
        var user = await dbContext.Users.FindAsync(userId, cancellationToken);
        ExceptionHelper.ThrowIfNull(user, "数据不存在");

        if (user.Email != request.Email)
        {
            var emailExist = await dbContext.Users
                .AnyAsync(x => x.Email == request.Email && x.Id != userId, cancellationToken);
            ExceptionHelper.ThrowIfTrue(emailExist, "邮箱已被占用");
        }

        if (user.PhoneNumber != request.PhoneNumber)
        {
            var phoneNumberExist = await dbContext.Users
                .AnyAsync(x => x.PhoneNumber.Value == request.PhoneNumber && x.Id != userId, cancellationToken);
            ExceptionHelper.ThrowIfTrue(phoneNumberExist, "手机号码已被占用");
        }

        user.SetEmail(request.Email);
        user.ChangeNickname(request.Nickname);
        user.SetPhoneNumber(request.PhoneNumber ?? "", false);
        user.SetSignature(request.Signature);

        dbContext.Users.Update(user);

        var result = await dbContext.SaveChangesAsync(cancellationToken) > 0;
        return await Result<bool>.SucceedAsync(result, result, ["修改失败"]);
    }
}
